MIT 6.172 L4 Assembly Language and Computer Architecture Part 1
课程主页:
课程视频:
https://www.bilibili.com/video/BV1wA411h7N7
这次回顾第四讲,这一讲介绍了汇编语言以及计算机体系结构。
备注:由于这次内容比较多,所以分为两次回顾,这次先回顾X86-64 ISA PRIMER以及FLOATING-POINT AND VECTOR HARDWARE。
源代码到执行
从源代码到执行一共分为四个阶段:
- 预处理(Preprocessing)
- 编译(Compiling)
- 汇编(Assembling)
- 链接(Linking)
步骤1,2如下图所示:
汇编语言提供了方便的机器代码符号表示。
反汇编
对于二进制文件,可以利用反汇编指令得到汇编代码:
objdump -S fib
得到如下结果:
学习汇编的意义
为什么要看程序的汇编代码呢?
- 该程序集显示了编译器做了什么和没有做什么。
- 漏洞可能会在较低级别出现。 例如,代码中的错误仅在–O3编译时才有效。 此外,有时编译器是漏洞的根源!
- 当所有其他方法均失败时,可以手动修改汇编代码。
- 逆向工程:当只能访问程序的二进制文件时,可以解密程序的工作。
X86-64 ISA PRIMER
这部分可以参考之前整理的资料,这里只补充之前不熟悉的部分:
https://doraemonzzz.com/2020/05/18/CMU%2015-213%20Intro%20to%20Computer%20Systems%20Lecture%205/
https://doraemonzzz.com/2020/05/19/CMU%2015-213%20Intro%20to%20Computer%20Systems%20Lecture%206/
x86-64常用寄存器
x86-64数据类型
后缀的含义
RFLAGS寄存器
算术和逻辑运算会更新RFLAGS寄存器中的状态标志,全部状态如下:
几个具体例子:
- CF:最后一个ALU运算从最高有效位产生进位或借位。
- ZF:上一次ALU运算的结果为0。
- SF:最后一个ALU操作产生一个其符号位已设置的值。
- OF:最后一个ALU操作导致算术溢出。
FLOATING-POINT AND VECTOR HARDWARE
浮点数指令集
现代的x86-64架构通过几个不同的指令集支持标量(即非矢量)浮点运算。
- SSE和AVX指令支持单精度和双精度标量浮点数算法,即“float”和“double”。
- x87指令支持单精度,双精度和扩展精度标量浮点运算,即“float”,“double”和“long double”。
SSE和AVX指令集还包括向量指令。
标量浮点的SSE
编译器比x87指令更喜欢使用SSE指令,因为SSE指令更易于编译和优化。
- SSE用于浮点值的操作码类似于x86_64操作码。
- SSE操作数使用XMM寄存器和浮点类型。
SSE操作码后缀
SSE指令使用两个字母的后缀来编码数据类型:
备注:
- 第一个字母single或packed(即vector)
- 第二个字母区分single-precision或double-precision
Vector Hardware
现代微处理器通常结合向量硬件,以单指令流,多数据流(SIMD)的方式处理数据。
- 令$k$表示向量宽度。
- 每个向量寄存器保存$k$个标量整数或浮点值。
- 该单元包含$k$个向量通道,每个通道包含标量整数或浮点硬件。
- 所有向量通道均以固定步长运行,并使用相同的指令和控制信号。
向量指令
向量指令通常以元素方式运行:
- 一个向量寄存器的第$i$个元素只能与其他向量寄存器的第$i$个元素一起参与运算。
- 所有通道对向量的各个元素执行完全相同的操作。
- 根据体系结构,向量内存操作数可能需要对齐,这意味着它们的地址必须是向量宽度的倍数。
- 一些架构支持跨通道操作,例如插入或提取向量元素的子集,对向量进行排列(也称为改组),分散或聚集。
向量指令集
现代的x86-64体系结构支持多个向量指令集。
- 现代的SSE指令集支持对整数,单精度和双精度浮点值进行向量运算。
- AVX指令支持对单精度和双精度浮点值进行向量运算。
- AVX2指令将整数向量运算添加到AVX指令集。
- AVX-512(AVX3)指令将寄存器长度增加到512位,并提供了新的向量运算,包括popcount。(在Haswell上不可用。)
SSE Versus AVX and AVX2
AVX和AVX2指令集以几种方式扩展了SSE指令集。
- SSE指令使用128位XMM向量寄存器,并且一次最多可操作2个操作数。
- AVX指令还可以使用256位YMM向量寄存器,并且一次可以对3个操作数进行操作:两个源操作数和一个不同的目标操作数。
AVX指令:
vaddpd %ymm0, %ymm1, %ymm2
SSE和AVX向量操作码
许多SSE和AVX操作码与传统的x86-64操作码相似,但有细微差别:
向量寄存器别名
像通用寄存器一样,XMM和YMM向量寄存器也是别名。